package com.flbill.controller;

import com.flbill.common.result.Result;
import com.flbill.pojo.dto.ReportDTO;
import com.flbill.pojo.entity.Expense;
import com.flbill.pojo.entity.Income;
import com.flbill.pojo.vo.ExpenseReportVO;
import com.flbill.pojo.vo.IncomeReportVO;
import com.flbill.service.ReportService;
import com.flbill.service.UserService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.InputStream;

@RestController
@RequestMapping("/api/report")
public class ReportController {
    private  final ReportService reportService;
    private final UserService userService;

    public ReportController(ReportService reportService, UserService userService) {
        this.reportService = reportService;
        this.userService = userService;
    }

    //支出扇形图
    @GetMapping("/expense-pie")
    public Result<ExpenseReportVO> expensePie(
            @RequestParam(required = false) String time_range,
            @RequestParam(required = false) LocalDate start_date,
            @RequestParam(required = false) LocalDate end_date) {

        ReportDTO reportDTO = new ReportDTO();
        reportDTO.setTimeRange(time_range);
        reportDTO.setStartDate(start_date);
        reportDTO.setEndDate(end_date);

        ExpenseReportVO expenseReportVO = reportService.expensePie(reportDTO);
        return Result.success(expenseReportVO);
    }

    //收入扇形图
    @GetMapping("/income-pie")
    public Result<IncomeReportVO> incomePie(
            @RequestParam(required = false) String time_range,
            @RequestParam(required = false) LocalDate start_date,
            @RequestParam(required = false) LocalDate end_date) {

        ReportDTO reportDTO = new ReportDTO();
        reportDTO.setTimeRange(time_range);
        reportDTO.setStartDate(start_date);
        reportDTO.setEndDate(end_date);

        IncomeReportVO incomeReportVO = reportService.incomePie(reportDTO);
        return Result.success(incomeReportVO);
    }

    // 支出分类柱状图
    @GetMapping("/expense-bar")
    public Result<List<Map<String, Object>>> expenseBar(
            @RequestParam(required = false) String time_range,
            @RequestParam(required = false) LocalDate start_date,
            @RequestParam(required = false) LocalDate end_date) {
        ReportDTO reportDTO = new ReportDTO();
        reportDTO.setTimeRange(time_range);
        reportDTO.setStartDate(start_date);
        reportDTO.setEndDate(end_date);
        return Result.success(reportService.expenseBar(reportDTO));
    }

    // 收入分类柱状图
    @GetMapping("/income-bar")
    public Result<List<Map<String, Object>>> incomeBar(
            @RequestParam(required = false) String time_range,
            @RequestParam(required = false) LocalDate start_date,
            @RequestParam(required = false) LocalDate end_date) {
        ReportDTO reportDTO = new ReportDTO();
        reportDTO.setTimeRange(time_range);
        reportDTO.setStartDate(start_date);
        reportDTO.setEndDate(end_date);
        return Result.success(reportService.incomeBar(reportDTO));
    }

    @Transactional
    @PostMapping("/export")
    public void exportReport(@RequestBody ReportDTO reportDTO, HttpServletResponse response) throws Exception {
        try (InputStream is = getClass().getClassLoader().getResourceAsStream("Export_file/report.xlsx");
             Workbook workbook = new XSSFWorkbook(is)) {
            Sheet sheet = workbook.getSheetAt(0);

            // 汇总数据
            ExpenseReportVO expenseReportVO = reportService.expensePie(reportDTO);
            IncomeReportVO incomeReportVO = reportService.incomePie(reportDTO);
            // 明细流水
            List<Income> incomeDetails = reportService.incomeDetails(reportDTO);
            List<Expense> expenseDetails = reportService.expenseDetails(reportDTO);

            System.out.println("incomeDetails size: " + incomeDetails.size());
            System.out.println("expenseDetails size: " + expenseDetails.size());
            System.out.println("expenseReportVO: " + expenseReportVO);
            System.out.println("incomeReportVO: " + incomeReportVO);

            // 3. 概要数据部分，先创建对应行再写入，避免覆盖表头
            Row summaryRow = sheet.getRow(2);
            if (summaryRow == null) summaryRow = sheet.createRow(2);
            summaryRow.createCell(0).setCellValue(expenseReportVO.getActual_expense() == null ? 0 : expenseReportVO.getActual_expense());
            summaryRow.createCell(1).setCellValue(incomeReportVO.getOther_income() == null ? 0 : incomeReportVO.getOther_income());
            summaryRow.createCell(2).setCellValue("时间:" + ("year".equals(reportDTO.getTimeRange()) ? "年" : ("month".equals(reportDTO.getTimeRange()) ? "月" : "周")));
            summaryRow.createCell(3).setCellValue(expenseReportVO.getActual_expense()>userService.getExpectedExpense()?"超出预算":"未超出预算");

            // 4. 填充收入明细（从第7行开始）
            int incomeStartRowIdx = 5; // 收入明细表头行索引
            Row incomeHeader = sheet.getRow(incomeStartRowIdx);
            if (incomeHeader == null) incomeHeader = sheet.createRow(incomeStartRowIdx);
            incomeHeader.createCell(0).setCellValue("金额");
            incomeHeader.createCell(1).setCellValue("时间");
            incomeHeader.createCell(2).setCellValue("类型");
            incomeHeader.createCell(3).setCellValue("备注");

            int incomeDataStartRowIdx = incomeStartRowIdx + 1; // 收入明细数据起始行索引
            for (int i = 0; i < incomeDetails.size(); i++) {
                Income income = incomeDetails.get(i);
                Row row = sheet.createRow(incomeDataStartRowIdx + i);
                row.createCell(0).setCellValue(income.getAmount() == null ? 0 : income.getAmount());
                row.createCell(1).setCellValue(income.getIncomeTime() == null ? "" : income.getIncomeTime().toString());
                row.createCell(2).setCellValue(income.getIncomeClass() == null ? "" : income.getIncomeClass());
                row.createCell(3).setCellValue(income.getRemark() == null ? "" : income.getRemark());
            }

            // 5. 填充支出明细（从收入明细数据结束的下一行开始）
            int expenseStartRowIdx = incomeDataStartRowIdx + incomeDetails.size(); // 支出明细表头行索引
            Row expenseHeader = sheet.getRow(expenseStartRowIdx);
            if (expenseHeader == null) expenseHeader = sheet.createRow(expenseStartRowIdx);
            expenseHeader.createCell(0).setCellValue("金额");
            expenseHeader.createCell(1).setCellValue("时间");
            expenseHeader.createCell(2).setCellValue("类型");
            expenseHeader.createCell(3).setCellValue("备注");

            int expenseDataStartRowIdx = expenseStartRowIdx + 1; // 支出明细数据起始行索引
            for (int i = 0; i < expenseDetails.size(); i++) {
                Expense expense = expenseDetails.get(i);
                Row row = sheet.createRow(expenseDataStartRowIdx + i);
                row.createCell(0).setCellValue(expense.getAmount() == null ? 0 : expense.getAmount());
                row.createCell(1).setCellValue(expense.getExpenseTime() == null ? "" : expense.getExpenseTime().toString());
                row.createCell(2).setCellValue(expense.getExpenseClass() == null ? "" : expense.getExpenseClass());
                row.createCell(3).setCellValue(expense.getRemark() == null ? "" : expense.getRemark());
            }

            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=report.xlsx");
            workbook.write(response.getOutputStream());
            response.getOutputStream().flush();
        }
    }

}
